﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Xml.Linq;
using ClosedXML.Excel;

namespace NyanBankIntfTool
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        //readonly OldLogger Logger;
        private readonly ProcessBarController processBarController;
        private BankIntfParser bankIntfParser;
        private FlowDocument flow;
        private readonly Paragraph para;

        public MainWindow()
        {
            InitializeComponent();

            var xml = XElement.Load(@".\Config\Config.xml");
            var configs = xml.Elements("Configs");
            var config = xml.Elements("Config");
            var query = from t in xml.Elements("Config") where t.Attribute("Name").Value == "FileListConfigFile" select t.Attribute("Value").Value;
            if (query.Any())
            {
                var a = query.First();
                //var a = query.First().Attribute("Value").Value;
            }

            var ver = typeof(App).Assembly.GetName().Version;
            Title += $" V{ver.Major}.{ver.Minor}.{ver.Revision}";

            //Logger = OldLogger.GetInstance();
            //TbLog.DataContext = oldLogger;

            processBarController = ProcessBarController.GetInstance();
            PbCurrent.DataContext = processBarController;
            PbParse.DataContext = processBarController;


            flow = new FlowDocument();
            para = new Paragraph();
            flow.Blocks.Add(para);
            RtbLog.Document = flow;
            Logger.LogEvent += OnLog;

            Logger.Log("才不是日志", LogLevel.Output);

            DirectoryInfo dir = new DirectoryInfo(TbDbfPathCmds.Text);
            foreach (var f in dir.EnumerateFiles("*.dbf").Reverse())
            {
                string fileName = f.Name;
                Match match;
                match = Regex.Match(fileName, @"([0-9]{8})(.*)");
                if (match.Success)
                {
                    var groups = match.Groups;
                    TbBusinDate.Text = groups[1].Value;
                    TbBusinDateCstp.Text = groups[1].Value;
                    break;
                }
            }
        }

        private void OnLog(Object sender, LogText logText)
        {
            Application.Current.Dispatcher.Invoke(new Action(() =>
            {
                var run = new Run(logText.Text);
                run.Foreground = logText.Brush;
                para.Inlines.Add(run);
            }));
        }

        private void ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
        }

        private void ParseCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
            }
            else if (e.Cancelled)
            {
                Logger.Log("操作已取消。");
                EnableControls();
            }
            else
            {
                EnableControls();
            }
        }

        private void DoStart(object sender, DoWorkEventArgs e)
        {
            //BackgroundWorker worker = sender as BackgroundWorker;

            BankIntfParser bankIntfDataParser = (BankIntfParser) e.Argument;
            bankIntfDataParser.DoParse();
        }

        private void DisableControls()
        {
            GdDataParseCmds.IsEnabled = false;
            GdStatus.IsEnabled = false;
            //GdDataParseCmds.Effect = new BlurEffect() {Radius = 20};
        }

        private void EnableControls()
        {
            GdDataParseCmds.IsEnabled = true;
            GdStatus.IsEnabled = true;
            //GdDataParseCmds.Effect = null;
        }

        private void ShowError(string text)
        {
            MessageBox.Show(text, "出错啦！", MessageBoxButton.OK, MessageBoxImage.Error);
        }

        private bool VerifyDataCmds()
        {
            if ((!(bool) CbParseDbfCmds.IsChecked && !(bool) CbParseLog.IsChecked) ||
                (!(bool) CbBusinDate.IsChecked && !(bool) CbNonBusinDate.IsChecked) && !(bool) CbStableDate.IsChecked)
            {
                var ret = MessageBox.Show("你确定要空跑吗？", "出错啦！", MessageBoxButton.YesNo, MessageBoxImage.Asterisk);
                if (ret == MessageBoxResult.Yes)
                {
                    MessageBox.Show("别想了，不支持空跑的。", "出错啦！", MessageBoxButton.OK, MessageBoxImage.Asterisk);
                }

                return false;
            }

            DateTime fakeDateTime;
            if ((bool) CbBusinDate.IsChecked && (TbBusinDate.Text == "" || !DateTime.TryParseExact(TbBusinDate.Text,
                                                     "yyyyMMdd", CultureInfo.CurrentCulture, DateTimeStyles.None,
                                                     out fakeDateTime)))
            {
                ShowError("业务验收日期为空或格式不正确，请检查！");
                return false;
            }

            if ((bool) CbNonBusinDate.IsChecked && (TbNonBusinDate.Text == "" || !DateTime.TryParseExact(
                                                        TbNonBusinDate.Text,
                                                        "yyyyMMdd", CultureInfo.CurrentCulture, DateTimeStyles.None,
                                                        out fakeDateTime)))
            {
                ShowError("非业务验收日期为空或格式不正确，请检查！");
                return false;
            }

            if ((bool) CbNonBusinDays.IsChecked && TbNonBusinDays.Text == "")
            {
                ShowError("请输入非业务验收天数！");
                return false;
            }

            if ((bool) CbStableDate.IsChecked && (TbStableDate.Text == "" || !DateTime.TryParseExact(TbStableDate.Text,
                                                      "yyyyMMdd", CultureInfo.CurrentCulture, DateTimeStyles.None,
                                                      out fakeDateTime)))
            {
                ShowError("稳定性验收日期为空或格式不正确，请检查！");
                return false;
            }

            if ((bool) CbStableDays.IsChecked && TbStableDays.Text == "")
            {
                ShowError("请输入稳定性验收天数！");
                return false;
            }

            return true;
        }

        private void BtStart_Click(object sender, RoutedEventArgs e)
        {
            PbCurrent.Value = 0;
            PbParse.Value = 0;
            //Logger.LogText = "";

            BackgroundWorker backgroundWorker = new BackgroundWorker
            {
                WorkerReportsProgress = true,
                WorkerSupportsCancellation = true
            }; //后台作业对象
            backgroundWorker.DoWork += DoStart;
            backgroundWorker.ProgressChanged += ProgressChanged;
            backgroundWorker.RunWorkerCompleted += ParseCompleted;

            if (TiCmds.IsSelected)
            {
                Logger.Log("当前选择的是CMDS");
                if (!VerifyDataCmds()) return;
                bankIntfParser = new BankIntfParser
                {
                    IsParseDbf = (bool) CbParseDbfCmds.IsChecked,
                    IsParseLog = (bool) CbParseLog.IsChecked,

                    ParseType = ParseTypes.CMDS, //CMDS

                    DbfPath = TbDbfPathCmds.Text, //DBF文件路径
                    OutputPath = TbOutputPathCmds.Text, //输出路径
                    //LogPath = TbLogPath.Text,
                    IMixLogFileName = TbIMixLogPath.Text,
                    ClientLogFileName = TbClientLogPath.Text,

                    IsOutputExtraExcel = (bool) CbOutputExtraExcel.IsChecked,
                    IsOutput2Template = (bool) CbOutputToTemplate.IsChecked,

                    BusinBeginTime = (bool) CbBusinBeginTime.IsChecked ? TbBusinBeginTime.Text : "",
                    BusinEndTime = (bool) CbBusinEndTime.IsChecked ? TbBusinEndTime.Text : "",
                    BusinDate = (bool) CbBusinDate.IsChecked ? TbBusinDate.Text : "",

                    StableDate = (bool) CbStableDate.IsChecked ? TbStableDate.Text : "",
                    StableDays = (bool) CbStableDays.IsChecked ? TbStableDays.Text : "",

                    NonBusinDate = (bool) CbNonBusinDate.IsChecked ? TbNonBusinDate.Text : "",
                    NonBusinDays = (bool) CbNonBusinDays.IsChecked ? TbNonBusinDays.Text : ""
                }; //数据分析对象
            }
            else if (TiCstp.IsSelected)
            {
                Logger.Log("当前选择的是CSTP");
                bankIntfParser = new BankIntfParser
                {
                    IsParseDbf = (bool) CbParseDbfCstp.IsChecked,
                    //IsParseLog = (bool) CbParseLog.IsChecked,

                    ParseType = ParseTypes.CSTP, //CMDS

                    DbfPath = TbDbfPathCstp.Text, //DBF文件路径
                    OutputPath = TbOutputPathCstp.Text, //输出路径
                    //LogPath = TbLogPath.Text,
                    //IMixLogFileName = TbIMixLogPath.Text,
                    //ClientLogFileName = TbClientLogPath.Text,

                    IsOutputExtraExcel = (bool) CbOutputExtraExcelCstp.IsChecked,
                    IsOutput2Template = (bool) CbOutputToTemplateCstp.IsChecked,
                    IsOutputAbnormalData = (bool) CbOutputAbnormalData.IsChecked,

                    BusinBeginTime = (bool) CbBusinBeginTimeCstp.IsChecked ? TbBusinBeginTimeCstp.Text : "",
                    BusinEndTime = (bool) CbBusinEndTimeCstp.IsChecked ? TbBusinEndTimeCstp.Text : "",
                    BusinDate = (bool) CbBusinDateCstp.IsChecked ? TbBusinDateCstp.Text : "",

                    //StableDate = (bool) CbStableDate.IsChecked ? TbStableDate.Text : "",
                    //StableDays = (bool) CbStableDays.IsChecked ? TbStableDays.Text : "",

                    //NonBusinDate = (bool) CbNonBusinDate.IsChecked ? TbNonBusinDate.Text : "",
                    //NonBusinDays = (bool) CbNonBusinDays.IsChecked ? TbNonBusinDays.Text : ""
                }; //数据分析对象
            }
            else
            {
                ShowError("请在CMDS页面或者CSTP页面执行！");
                return;
            }

            DisableControls();
            backgroundWorker.RunWorkerAsync(bankIntfParser);
        }

        private void BtBrowserDbfPathCmds_Click(object sender, RoutedEventArgs e)
        {
            var folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();

            if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                TbDbfPathCmds.Text = folderBrowserDialog.SelectedPath;
            }
        }

        private void BtBrowserOutputPathCmds_Click(object sender, RoutedEventArgs e)
        {
            var folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
            folderBrowserDialog.SelectedPath = Environment.CurrentDirectory;

            if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                TbOutputPathCmds.Text = folderBrowserDialog.SelectedPath;
            }
        }

        private void CbLogAutoScroll_Checked(object sender, RoutedEventArgs e)
        {
            RtbLog.ScrollToEnd();
        }

        private void BtBrowserClientLogPath_Click(object sender, RoutedEventArgs e)
        {
            //var folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
            var openFileDialog = new System.Windows.Forms.OpenFileDialog();
            openFileDialog.InitialDirectory = Environment.CurrentDirectory;

            if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                TbClientLogPath.Text = openFileDialog.FileName;
            }
        }

        private void BtBrowserIMixLogPath_Click(object sender, RoutedEventArgs e)
        {
            var openFileDialog = new System.Windows.Forms.OpenFileDialog();
            openFileDialog.InitialDirectory = Environment.CurrentDirectory;

            if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                TbIMixLogPath.Text = openFileDialog.FileName;
            }
        }

        private void CbParseLog_Click(object sender, RoutedEventArgs e)
        {
            if (!(bool) CbParseDbfCmds.IsChecked && !(bool) CbParseLog.IsChecked) GdBusinDate.IsEnabled = false;
            else GdBusinDate.IsEnabled = true;

            if ((bool) CbParseLog.IsChecked)
            {
                Logger.Log(
                    "已勾选解析日志，请注意选择IMix日志文件（业务日志使用）路径与Client日志文件（非业务与稳定性使用）路径，并按需要勾选并填写业务验收日期与时间、稳定性业务验收日期与天数、非业务验收日期与天数。",
                    LogLevel.Output);
            }
            else
            {
                Logger.Log("已取消勾选解析日志。", LogLevel.Output);
            }
        }

        private void RtbLog_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (CbLogAutoScroll.IsChecked == true)
            {
                RtbLog.ScrollToEnd();
            }
        }

        private void CbParseDbfCmds_Click(object sender, RoutedEventArgs e)
        {
            if (!(bool) CbParseDbfCmds.IsChecked && !(bool) CbParseLog.IsChecked) GdBusinDate.IsEnabled = false;
            else GdBusinDate.IsEnabled = true;
            if ((bool) CbParseDbfCmds.IsChecked)
            {
                Logger.Log("已勾选解析DBF，请勾选并填写业务验收日期与时间（可选）。", LogLevel.Output);
            }
            else
            {
                Logger.Log("已取消勾选解析DBF。", LogLevel.Output);
            }
        }


        private void TbBusinDate_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (TbIMixLogPath.Text.Contains(@".\Log\CMDS"))
            {
                TbIMixLogPath.Text = $@".\Log\CMDS{TbBusinDate.Text}.log";
            }
        }

        private void CbParseDbfCstp_Click(object sender, RoutedEventArgs e)
        {
            if (!(bool) CbParseDbfCstp.IsChecked) GdBusinDateCstp.IsEnabled = false;
            else GdBusinDateCstp.IsEnabled = true;
            if ((bool) CbParseDbfCstp.IsChecked)
            {
                Logger.Log("已勾选解析DBF，请勾选并填写业务验收日期与时间（可选）。", LogLevel.Output);
            }
            else
            {
                Logger.Log("已取消勾选解析DBF。", LogLevel.Output);
            }
        }

        private void BtBoom_Click(object sender, RoutedEventArgs e)
        {
            throw new InvalidOperationException();
        }

        private void BtBrowserDbfPathCstp_Click(object sender, RoutedEventArgs e)
        {
            var folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();

            if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                TbDbfPathCstp.Text = folderBrowserDialog.SelectedPath;
            }
        }

        private void BtBrowserOutputPathCstp_Click(object sender, RoutedEventArgs e)
        {
            var folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();

            if (folderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                TbOutputPathCstp.Text = folderBrowserDialog.SelectedPath;
            }
        }

        private void TbOutputPathCmds_TextChanged(object sender, TextChangedEventArgs e)
        {
        }

        private void TbDbfPathCmds_TextChanged(object sender, TextChangedEventArgs e)
        {
        }

        private void Bt_Up_Click(object sender, RoutedEventArgs e)
        {
            var wb = new XLWorkbook(@".\基金银行间id.xlsx");
            var ws = wb.Worksheets.First();

            for (int i = 2;; i++)
            {
                if (ws.Cell(i, 1).GetString() == "") break;
                string sql =
                    @"update tfundinfo t set t.L_BANK_ID = :2, t.VC_SHCLEARING_ACCOUNT = :3, t.VC_BANK_ACCOUNT = :4 where t.l_fund_id = :1;";
                sql = sql.Replace(":1", ws.Cell(i, 1).GetString());
                sql = sql.Replace(":2", ws.Cell(i, 2).GetString());
                sql = sql.Replace(":3", ws.Cell(i, 3).GetString());
                sql = sql.Replace(":4", ws.Cell(i, 4).GetString());
                Logger.Log(sql);
            }
        }
    }
}